ccR.Add_Rotation(
		3,
		"CDM_Shaman_Restoration",
		"cdMichealB's fantastic healing.",
		"CDM_Shaman_Restoration_Talents",
		"CDM_Shaman_Restoration_Abilities",
		"CDM_Shaman_Restoration_Features",
		"CDM_Shaman_Restoration_Setup"
)
											--Player Skills
											local RIPTIDE = 61295
											local HEALING_SURGE = 8004
											local TIDAL_WAVES = 53390
											local HEALING_WAVE = 77472
											local UNLEASH_LIFE = 73685
											local HEALING_STREAM_TOTEM = 5394
											local CHAIN_HEAL = 1064
											local HEALING_RAIN = 73920
											local ANCESTRAL_SWIFTNESS = 16188
											local WATER_SHIELD = 52127
											local EARTH_SHIELD = 974
											local ELEMENTAL_BLAST = 117014
											local ASCENDANCE = 165344
											local SPIRIT_LINK_TOTEM = 98008
											local SPIRITWALKERS_GRACE = 79206
											local LIGHTNING_BOLT = 403
											local CLOUDBURST_TOTEM = 157153
											local HEALING_TIDE_TOTEM = 108280
											local SEARING_TOTEM = 3599
											local FLAME_SHOCK = 8050
											local LAVA_BURST = 51505
											local FROST_SHOCK = 8056
											local ELEMENTAL_MASTERY = 16166
											local ANCESTRAL_GUIDANCE = 108281
											local PRIMAL_ELEMENTALIST = 117013
											local EARTH_ELEMENTAL_TOTEM = 2062
											local FIRE_ELEMENTAL_TOTEM = 2894
											local EMPOWER = 118350
											local REINFORCE = 118347
											local WINDSHEER = 57994

																							--Kargath Bladefist
																							local KA_IMPALE = 159113 
																							--The Butcher
																							local BU_CLEAVE = 156157
																							local BU_GUSHING_WOUNDS = 156152

																							--Tectus
																							local TE_TECTONIC_UPHEAVAL = 162475

																							--Brackenspore
																							local BR_INFESTING_SPORES = 163242
																							local BR_LIVING_SPORES = 159463
																							local BR_DECAY = 160013
																							local BR_NECROTIC_BREATH = 159220
																							local BR_GREEN_WITHERING = 160399
																							local BR_GREEN_WITHERING_FAST = 163113
																							local BR_BLUE_WITHERING = 163122
																							local BR_BLUE_WITHERING_FAST = 163124

																							--Twin Orgron
																							local OR_INTERRUPTING_SHOUT = 158102


																							--Ko'ragh
																							local KO_EXPEL_MAGIC_SHADOW = 162184 --Expel Magic: Shadow
																							local KO_EXPEL_MAGIC_FIRE = 162185
																							local KO_EXPEL_MAGIC_FROST = nil
																							local KO_EXPEL_MAGIC_ARCANE = 162186
																							local KO_CAUSTIC_ENERGY = 161242
																							local KO_SUPPRESSION_FIELD = 161328

	local LoDCount = {}
	local HRCount = {}
	local AoECount = {}
	local AutoMoveCount = {}
	local WildCount = {}
	local ClusterCount = {}
	local ClusterPreCount = {}
	local GenesisCount = {}
	onlyPlayers = true
	local BossTarget = nil
	local TrashTarget = nil
	local LowestHP = nil
	local SecondLowestHP = nil
	local Tank1 = nil
	local Tank2 = nil
	local vUnit = nil
	local RejShroom = nil
	local LifeShroom = nil
	local foundLifeBloom = nil
	local BossTarget = nil
	local TrashTarget = nil
	local HRCount = {}
	local HRTarg = nil
	local AoECount = {}
	local AoETarg = nil
	local LoDCount = {}
	local HighestTank = nil
	local LowestTank = nil

function CDM_Shaman_Restoration()
	
	table.wipe(LoDCount)
	table.wipe(HRCount)
	table.wipe(AoECount)
	LowestHP = "player"
	SecondLowestHP = "player"
	Tank1 = nil
	Tank2 = nil
	HRTarg = nil
	AoETarg = nil
	RejShroom = nil
	LifeShroom = nil
	BossTarget = nil
	TrashTarget = nil
	HighestTank = nil
	LowestTank = nil

	if not ccR.Unit.Exists(Tank1) or not ccR.Unit.Is.Tank(vUnit) then
		Tank1 = nil
	end
	if not ccR.Unit.Exists(Tank2) or not ccR.Unit.Is.Tank(vUnit) then
		Tank2 = nil
	end
--End declarations
	if not ccR.Unit.Has.MyBuff(LastFaith, BEACON_OF_FAITH) then
		LastFaith = nil
	end
	for i = 1, # ccR_Friendly do 
		local vUnit = ccR_Friendly[i]
		if ValidToHeal(vUnit, true) and ccR.Unit.Distance(vUnit, "player") <= 50 and (ccR.Unit.Is.APlayer(vUnit) or onlyPlayers == false or ccR.Unit.Name(vUnit) == "Rejuvenating Mushroom" or ccR.Unit.Name(vUnit) == "Living Mushroom") then
			if  ccR.Unit.Name(vUnit) == "Rejuvenating Mushroom" then
				RejShroom = vUnit
			end
			if ccR.Unit.Name(vUnit) == "Living Mushroom" then
				LifeShroom = vUnit
			end
			--Tanks
			if ccR.Unit.Is.APlayer(vUnit) and (Tank1 == nil or Tank2 == nil) then
				if ccR.Unit.Is.Tank(vUnit) and Tank1 == nil then
					Tank1 = vUnit
				elseif ccR.Unit.Is.Tank(vUnit) and Tank2 == nil then
					Tank2 = vUnit
				end
			end
			if ValidToHeal(vUnit) and not ccR.Unit.Has.Debuff(vUnit, BR_NECROTIC_BREATH) and ccR.Unit.Name(vUnit) ~= "Living Mushroom" then
				--Lowest HP
				if ccR.Unit.Health(vUnit) < ccR.Unit.Health(LowestHP) then
					SecondLowestHP = LowestHP
					LowestHP = vUnit
				elseif ccR.Unit.Health(vUnit) == ccR.Unit.Health(LowestHP) then
					if UnitHealthMax(vUnit) < UnitHealthMax(LowestHP) then
						SecondLowestHP = LowestHP
						LowestHP = vUnit
					else
						SecondLowestHP = vUnit
					end
				end
				--Counts
				if ccR.Unit.Health(vUnit) < 95  and ccR.Unit.Distance(vUnit, "player") <= 30 then
					--table.insert(LoDCount, vUnit)
					LoDCount[#LoDCount+1] = vUnit
				end

				if not HRTarg and ccR.Spell.Is.Ready(HOLY_RADIANCE) then
					for e = 1, # ccR_Friendly do
						local vvUnit = ccR_Friendly[e]
						if (ccR.Unit.Health(vvUnit) < 94 or ccR.Unit.Has.Debuff(vUnit, 162184)) and ccR.Unit.Distance(vvUnit, vUnit) <= 14 and (ccR.Unit.Is.APlayer(vUnit) or onlyPlayers == false) then
							--table.insert(HRCount, vvUnit)
							HRCount[#HRCount+1] = vvUnit
						end 
					end
					if # HRCount >= 4 then
						HRTarg = vUnit
					else
						table.wipe(HRCount)
					end
				end
				if not AoeTarg then
					for f = 1, # ccR_Friendly do
						local vvvUnit = ccR_Friendly[f]
						if ccR.Unit.Distance(vvvUnit, vUnit) <= 30 and (ccR.Unit.Health(vvvUnit) < 94 or ccR.Unit.Has.Debuff(vUnit, 162184)) and (ccR.Unit.Is.APlayer(vUnit) or onlyPlayers == false) then
							--table.insert(AoECount, vvvUnit)
							AoECount[#AoECount+1] = vvvUnit
						end 
					end
					if # AoECount >= 4 then
						AoETarg = vUnit
					else
						table.wipe(AoECount)
					end
				end
				--ccR.Paladin.Feature.Cleanse(vUnit)
			end
		end
	end
	if Tank1 and Tank2 and ccR.Unit.Health(Tank1) <= ccR.Unit.Health(Tank2) then
		LowestTank = Tank1
		HighestTank = Tank2
	elseif Tank1 and Tank2 and ccR.Unit.Health(Tank2) <= ccR.Unit.Health(Tank1) then
		LowestTank = Tank2
		HighestTank = Tank1
	elseif Tank1 then
		LowestTank = Tank1
	elseif Tank2 then
		LowestTank = Tank2
	end
	if LowestTank and LowestHP and ccR.Unit.Health(LowestHP) <= ccR.Unit.Health(LowestTank) then
		SmartHeal = LowestHP
	elseif not LowestTank and HighestTank and LowestHP and ccR.Unit.Health(LowestHP) <= ccR.Unit.Health(HighestTank) then
		SmartHeal = LowestHP
	elseif LowestTank then
		SmartHeal = LowestTank
	elseif HighestTank then 
		SmartHeal = HighestTank
	end

	Empower()
	Reinforce()
	Windsheer(1.5)
	HealingStreamTotem()
	CloudburstTotem()

	Riptide(LowestTank, 101)
	Riptide(HighestTank, 101)
	if not ccR.Player.Has.Buff(TIDAL_WAVES) then
		Riptide(LowestHP, 101)
	end
	UnleashLife(SmartHeal, 101)
	HealingSurge(SmartHeal, 10)
	WaterShield()
	HealingRain()
	--ChainHeal()
	HealingSurge(SmartHeal, 50)
	HealingWave(SmartHeal, 90)

	--SearingTotem()

end -- End Rotation


function Riptide(fUnit, fHealth, fMana)
	fUnit = fUnit or "player"
	fHealth = fHealth or 100
	fMana = fMana or 0
	if ccR.Spell.Is.Ready(RIPTIDE) and ValidToHeal(fUnit) and not ccR.Unit.Has.MyBuff(fUnit, RIPTIDE) and ccR.Unit.Health(fUnit) < fHealth and ccR.Player.Mana() >= fMana and DoHeal(fUnit) then
		ccR.Cast.Spell(RIPTIDE, fUnit)
	end
end
function HealingWave(fUnit, fHealth, fMana)
	fUnit = fUnit or "player"
	fHealth = fHealth or 100
	fMana = fMana or 0
	if ccR.Spell.Is.Ready(HEALING_WAVE) and ValidToHeal(fUnit) and ccR.Unit.Health(fUnit) < fHealth and ccR.Player.Mana() > fMana and DoHeal(fUnit) then
		ccR.Cast.Spell(HEALING_WAVE, fUnit)
	end
end
function HealingSurge(fUnit, fHealth, fMana)
	fUnit = fUnit or "player"
	fHealth = fHealth or 100
	fMana = fMana or 0
	if ccR.Spell.Is.Ready(HEALING_SURGE) and ValidToHeal(fUnit) and ccR.Unit.Health(fUnit) < fHealth and ccR.Player.Mana() > fMana and DoHeal(fUnit) then
		ccR.Cast.Spell(HEALING_SURGE, fUnit)
	end
end
function ChainHeal(fMana)
	fMana = fMana or 0
	if ccR.Spell.Is.Ready(CHAIN_HEAL) and ValidToHeal(AoETarg) and #AoECount >= 4 and ccR.Player.Mana() > fMana and DoHeal(AoETarg) then
		ccR.Cast.Spell(CHAIN_HEAL, AoETarg)
	end
end
function UnleashLife(fUnit, fHealth, fMana)
	fUnit = fUnit or "player"
	fHealth = fHealth or 100
	fMana = fMana or 0
	if ccR.Spell.Is.Ready(UNLEASH_LIFE) and ValidToHeal(fUnit) and ccR.Unit.Health(fUnit) < fHealth and ccR.Player.Mana() > fMana and DoHeal(fUnit) then
		ccR.Cast.Spell(UNLEASH_LIFE, fUnit)
	end
end
function ElementalBlast()

	ccR.Cast.Spell(ELEMENTAL_BLAST)
end
function ElementalMastery()

	ccR.Cast.Spell(ELEMENTAL_MASTERY)
end
function Ascendance()
	
	ccR.Cast.Spell(ASCENDANCE)
end
function AncestralSwiftness()

	ccR.Cast.Spell(ANCESTRAL_SWIFTNESS)
end
function AncestralGuidance()

	ccR.Cast.Spell(ANCESTRAL_GUIDANCE)
end
function Empower()
	if ccR.Player.HasTotem(FIRE_ELEMENTAL_TOTEM) then
		ccR.Cast.Spell(EMPOWER)
	end
end
function Reinforce()
	if ccR.Player.HasTotem(EARTH_ELEMENTAL_TOTEM) then
		ccR.Cast.Spell(REINFORCE)
	end
end
function HealingRain(fCount)
	fCount = fCount or 5
	--if ccR.Spell.Is.Ready(HEALING_RAIN) and # AoECount >= fCount then
	--	ccR.Cast.Spell(HEALING_RAIN)
	--	if SpellIsTargeting() then CastAtPosition(GetAveragePositionOfObjects(AoECount)) end
	if ccR.Spell.Is.Ready(HEALING_RAIN) and # HRCount >= fCount then
		ccR.Cast.Spell(HEALING_RAIN)
		if SpellIsTargeting() then CastAtPosition(GetAveragePositionOfObjects(HRCount)) end
	--elseif ccR.Spell.Is.Ready(HEALING_RAIN) and # AoECount >= fCount-1 then
	--	ccR.Cast.Spell(HEALING_RAIN)
	--	if SpellIsTargeting() then CastAtPosition(GetAveragePositionOfObjects(AoECount)) end
	elseif ccR.Spell.Is.Ready(HEALING_RAIN) and # HRCount >= fCount-1 then
		ccR.Cast.Spell(HEALING_RAIN)
		if SpellIsTargeting() then CastAtPosition(GetAveragePositionOfObjects(HRCount)) end
	end
end
function HealingStreamTotem()
	if not ccR.Player.HasTotem(HEALING_TIDE_TOTEM) and not ccR.Player.HasTotem(CLOUDBURST_TOTEM) and not ccR.Player.HasTotem(HEALING_STREAM_TOTEM) and ccR.Spell.Is.Ready(HEALING_STREAM_TOTEM) then
		ccR.Cast.Spell(HEALING_STREAM_TOTEM)
	end
end
function CloudburstTotem()
	if not ccR.Player.HasTotem(HEALING_TIDE_TOTEM) and not ccR.Player.HasTotem(HEALING_STREAM_TOTEM) and not ccR.Player.HasTotem(CLOUDBURST_TOTEM) and ccR.Spell.Is.Ready(CLOUDBURST_TOTEM) then
		ccR.Cast.Spell(CLOUDBURST_TOTEM)
	end
end
function EarthShield()

end
function WaterShield()
	if not ccR.Player.Has.Buff(WATER_SHIELD) and ccR.Spell.Is.Ready(WATER_SHIELD) then
		ccR.Cast.Spell(WATER_SHIELD)
	end
end
function LightningBolt()

end
function AutoDps()

end
function SearingTotem()
	if (not ccR.Player.Has.Totem(SEARING_TOTEM) or (ccR.Player.Has.Totem(SEARING_TOTEM) and ccR.Target.Exists() and ccR.Target.Is.Attackable() and ccR.Player.Totem.Distance(SEARING_TOTEM, "target") >= 25))
	and ccR.Spell.Is.Ready(SEARING_TOTEM)
	and not ccR.Player.Has.Totem(FIRE_ELEMENTAL_TOTEM)
	then
		ccR.Cast.Spell(SEARING_TOTEM)
	end
end
function FlameShock()

end
function FrostShock()

end

function ValidToHeal(tunit, ignoreRange)
	if tunit and ccR.Unit.Exists(tunit) and ccR.Unit.Is.Alive(tunit) and ccR.Unit.Is.InLineOfSight(tunit) and DoHeal(tunit) then
		if ignoreRange then
			return true
		elseif ccR.Unit.Distance(tunit, "player") <= 40 then
			return true
		else
			return false
		end
	else
		return false
	end
end

function FindThreat()
		for x = 1, # ccR_Enemies_In_Combat do
			local vUnit = ccR_Enemies_In_Combat[x]
			if ccR.Unit.Is.Alive(vUnit)
			
			and ccR.Unit.Is.Attackable(vUnit)
			
			
			and ccR.Unit.Is.InCombat(vUnit)
			then
				if ccR.Unit.Is.Boss(vUnit) then
					BossTarget = vUnit
				else
					TrashUnit = vUnit
				end

			end
		end
end

function GetAveragePositionOfObjects (Objects)
	local Total = #Objects;
	local X, Y, Z = 0, 0, 0;
	
	for Key, ThisObject in pairs(Objects) do
		if ThisObject then
			local ThisX, ThisY, ThisZ =  ObjectPosition(ThisObject);
			if ThisX and ThisY then
				X = X + ThisX;
				Y = Y + ThisY;
				Z = Z + ThisZ;
			end
		end
	end

	X = X / Total;
	Y = Y / Total;
	Z = Z / Total;
	return X, Y, Z;
end

function DoHeal(fUnit)
 if ccR.Unit.Has.Debuff(fUnit, BR_NECROTIC_BREATH) then
 	return false
 else
 	return true
 end
end
function Windsheer(fTime)	
		fTime = fTime or 1
		if ccR.Spell.Is.Ready(WINDSHEER) then
			for x = 1, # ccR_Enemies_Within_44 do
				local vUnit = ccR_Enemies_Within_44[x]
				if ccR.Unit.Exists(vUnit)
				and ccR.Unit.Is.CastingOrChanneling(vUnit) 
				and ccR.Unit.Is.Interuptable(vUnit) 
				and (ccR.Player.Is.Facing(vUnit) or ccR.Var("fh_Always_Facing"))
				and ccR.Spell.CanAttack(WINDSHEER, vUnit)
				then 
					if ccR.Unit.Has.LeftOnCast(vUnit, fTime) then ccR.Cast.Attack(WINDSHEER, vUnit) end 
					if ccR.Unit.Is.Channeling(vUnit) then ccR.Cast.Attack(WINDSHEER, vUnit) end 
				end
			end
		end
end

function AutoPurge()
	for x = 1, #ccR_Enemies_Within_44 do
		local unit = ccR_Enemies_Within_44[x]
		if ccR.Unit.Exists(unit)
		and	ccR.Spell.Is.Ready(PURGE) 
		and ccR.Spell.CanAttack(PURGE, unit)
		and not ccR.Player.Is.CastingOrChanneling() 
		then
			for i = 1, 40 do 
			 	local name, _, _, _, buffType, _, _, _, _, _, buffID = UnitBuff(unit, i) 
			 	if name == nil then	
			 		break 
			 	else 
			 		if buffType == "Magic" then
			 			ccR.Cast.Spell(PURGE, unit)	
			 			ccR.PrintToChat("Purge: [ " .. buffID .. " ] " .. name .. " (" .. buffType .. ") " .. " on " .. unit .. " ( " .. ccR.Unit.Name(unit) .. " ).")
			 			return
			 		end
			 	end
			end
		end
	end
end